﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Linq;

using Bpms.Data;
using Bpms.Entity;
using Bpms.Log;
using Bpms.Cache;

namespace Bpms.Bll
{
    /// <summary>
    /// 业务类别逻辑操作类
    /// </summary>
    public class BusinessCategory
    {
        #region Member

        /// <summary>
        /// 类别删除结果枚举
        /// </summary>
        public enum BusinessCategoryDeleteResult
        {
            本类别下含有子类别,
            根类别下只剩最后一个类别,
            其他原因导致不可删除,
            可以删除,
            删除成功,
            删除失败
        }

        /// <summary>
        /// 数据库改动事件委托
        /// </summary>
        public delegate void DBChangedEventHandler();

        /// <summary>
        /// 日志事件委托
        /// </summary>
        public delegate void LogEventHandler();

        /// <summary>
        /// 数据库改动事件
        /// </summary>
        public static event DBChangedEventHandler DBChanged;

        /// <summary>
        /// 写日志事件
        /// </summary>
        public static event LogEventHandler WriteLog;

        #region Private
        private static IDataProvider provider = DatabaseProvider.GetInstance();
        static CacheContext cacheProvider = CacheContext.GetCacheService(new DefaultCache());

        static BusinessCategory()
        {
            provider.SetLog(new ExceptionLogAdapter());
        }

        /// <summary>
        /// 递归遍历树
        /// </summary>
        /// <param name="categorys"></param>
        /// <param name="rowHTML"></param>
        static void PopulateSubTree(IList<BusinessCategoryInfo> categorys, ref string rowHTML)
        {
            foreach (var category in categorys)
            {
                var childCategorys = GetInfoList(category.ID);

                rowHTML += AddNode(category);
                PopulateSubTree(childCategorys, ref rowHTML);
            }
        }


        /// <summary>
        /// 添加节点内容
        /// </summary>
        /// <param name="category"></param>
        /// <returns></returns>
        static string AddNode(BusinessCategoryInfo category)
        {
            var nodeHTML = new StringBuilder();
            var categoryName = string.Format(@"<td class=""{0}"" ><image style=""padding-left:{1}px;padding-right:8px;"" src=""../image/icon{2}.gif"" alt="""" /><input type=""hidden"" value=""{3}"" /><span>{4}</span></td>", category.Depth == 1 ? "category_o" : "category_t", 10 + (category.Depth - 1) * 15, category.Depth == 1 ? "1" : "2", category.ID, category.Name) + "\r\n";
            var addButton = string.Format(@"<td align=""center""><input type=""button"" class=""addBtn"" value=""添加"" />") + "\r\n";
            var editButton = string.Format(@"<input type=""button"" class=""addBtn"" value=""编辑"" />") + "\r\n";
            var deleteButton = string.Format(@"<input type=""button"" class=""addBtn"" value=""删除"" /></td>") + "\r\n";
            var inputText = string.Format(@"<td><input class=""input2"" size=""5"" type=""text"" value=""{0}"" />", category.SortNumber) + "\r\n";
            var setButton = string.Format(@"<input type=""button"" class=""addBtn""  value=""设置""/></td>") + "\r\n";

            nodeHTML.Append("<tr>\r\n");
            nodeHTML.Append(categoryName)
                .Append(addButton)
                .Append(editButton)
                .Append(deleteButton)
                .Append(inputText)
                .Append(setButton);
            nodeHTML.Append("</tr>\r\n");

            return nodeHTML.ToString();
        }

        /// <summary>
        /// 取缓存
        /// </summary>
        /// <returns></returns>
        static IList<BusinessCategoryInfo> GetCache()
        {
            return cacheProvider.RetrieveObject(CacheKey.BusinessCategoryList.ToString()) as IList<BusinessCategoryInfo>;
        }

        /// <summary>
        /// 加缓存
        /// </summary>
        /// <param name="cache"></param>
        static void AddCache(object cache)
        {
            cacheProvider.AddObject(CacheKey.BusinessCategoryList.ToString(), cache);
        }

        /// <summary>
        /// 数据改动事件处理函数
        /// </summary>
        static void OnDBChanged()
        {
            if (DBChanged != null)
            {
                DBChanged();
            }
        }

        /// <summary>
        /// 写日志处理函数
        /// </summary>
        static void OnWriteLog()
        {
            if (WriteLog != null)
            {
                WriteLog();
            }
        }
        #endregion

        #endregion

        /// <summary>
        /// 添加业务类别
        /// </summary>
        /// <param name="businessCategory">业务类别</param>
        /// <returns>-1：记录已经存在；0：失败；1：成功</returns>
        public static int Insert(BusinessCategoryInfo businessCategory)
        {
            if (provider.BusinessCategoryExists(businessCategory, OperateType.Insert))
            {
                return -1;
            }
            if (provider.InsertBusinessCategory(businessCategory))
            {
                OnDBChanged();
                OnWriteLog();
                return 1;
            }

            return 0;


        }

        /// <summary>
        /// 更新业务类别
        /// </summary>
        /// <param name="businessCategory">业务类别</param>
        /// <returns>-1：记录已经存在；0：失败；1：成功</returns>
        public static int Update(BusinessCategoryInfo businessCategory)
        {
            if (provider.BusinessCategoryExists(businessCategory, OperateType.Update))
            {
                return -1;
            }
            if (provider.UpdateBusinessCategory(businessCategory))
            {
                OnDBChanged();
                OnWriteLog();
                return 1;
            }

            return 0;
        }

        /// <summary>
        /// 删除业务类型
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public static BusinessCategoryDeleteResult Delete(int id)
        {
            var isDeleteableable = provider.IsBusinessCategoryDeleteable(id);

            switch (isDeleteableable)
            {
                case -1:
                    return BusinessCategoryDeleteResult.本类别下含有子类别;
                case -2:
                    return BusinessCategoryDeleteResult.根类别下只剩最后一个类别;
                case 0:
                    return BusinessCategoryDeleteResult.其他原因导致不可删除;
                case 1:
                    //可以删除
                    if (provider.DeleteBusinessCategory(id, false))
                    {
                        OnDBChanged();
                        return BusinessCategoryDeleteResult.删除成功;
                    }

                    return BusinessCategoryDeleteResult.删除失败;
                default:
                    return BusinessCategoryDeleteResult.删除失败;
            }
        }

        /// <summary>
        /// 返回类别信息
        /// </summary>
        /// <param name="id">类别ID</param>
        /// <returns></returns>
        public static BusinessCategoryInfo GetInfo(int id)
        {
            var cache = GetCache();

            if (cache == null)
            {
                return provider.GetBusinessCategory(id);
            }

            var result = from cacheItem in cache
                         where cacheItem.ID == id
                         select cacheItem;

            if (result.Count() > 0)
            {
                return result.First();
            }

            return null;
        }

        /// <summary>
        /// 根据父别类ID返回类别列表
        /// </summary>
        /// <param name="parentId">父类别ID</param>
        /// <returns></returns>
        public static IList<BusinessCategoryInfo> GetInfoList(int parentId)
        {
            var cache = GetCache();

            if (cache == null)
            {
                cache = provider.GetAllBusinessCategories();
                AddCache(cache);
            }

            var result = from cacheItem in cache
                         where cacheItem.ParentID == parentId
                         select cacheItem;

            var list = new List<BusinessCategoryInfo>();

            if (result != null)
            {
                foreach (var item in result)
                {
                    list.Add(item);
                }
            }

            return list;
        }

        /// <summary>
        /// 设置显示顺序
        /// </summary>
        /// <param name="parentId">父类别ID</param>
        /// <param name="categoryId">类别ID</param>
        /// <param name="sortNumber">显示顺序</param>
        /// <returns></returns>
        public static int SetSortNumber(int id, int sortNumber)
        {
            if (!provider.IsBusinessCategorySortable(id, (byte)sortNumber))
            {
                return -1;
            }
            if (provider.SetCategorySortNumber(id, sortNumber))
            {
                DBChanged();
                return 1;
            }

            return 0;
        }

        /// <summary>
        /// 根据类别ID返回类别名称
        /// </summary>
        /// <param name="id">类别ID</param>
        /// <returns></returns>
        public static string GetNameById(int id)
        {
            return provider.GetBusinessCategoryNameById(id);
        }

        /// <summary>
        /// 根据类别名称返回类别ID
        /// </summary>
        /// <param name="name">类别名称</param>
        /// <returns></returns>
        public static int GetIdByName(string name)
        {
            return provider.GetBusinessCategoryIdByName(name);
        }

        /// <summary>
        /// 返回生成的类别树HTML
        /// </summary>
        /// <param name="parentId">父ID</param>
        /// <returns></returns>
        public static string GetTreeHTML(int parentId)
        {
            var htmlText = string.Empty;
            var categorys = GetInfoList(parentId);

            if (categorys.Count > 0)
            {
                htmlText += @"<table id=""categoryTable"" width=""80%"" border=""0"" align=""center"" cellpadding=""0"" cellspacing=""0"" style=""margin-top: 30px;"">" + "\r\n";
                PopulateSubTree(categorys, ref htmlText);
                htmlText += "</table>\r\n";
            }

            return htmlText;
        }
    }
}
